﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using DevExpress.XtraBars;
using Moonlite.ExtensionApi.ControlInterfaces;
using Moonlite.Platform.General;

namespace Moonlite.UI.Shell.Controls {
    public partial class Output : UserControl, IOutput {
        public event OutputStreamEventHandler SelectedStreamChanged;
        public event OutputStreamEventHandler StreamAdded;
        public event OutputStreamEventHandler StreamRemoved;
        public event OutputStreamEventHandler StreamCleared;
        public event EventHandler AllStreamsCleared;
        private List<OutputStream> streams = new List<OutputStream>();
        protected virtual void OnSelectedStreamChanged(OutputStreamEventArgs e) {
            OutputStreamEventHandler handler = SelectedStreamChanged;
            if (handler != null) {
                handler(this, e);
            }
        }
        protected virtual void OnStreamAdded(OutputStreamEventArgs e) {
            OutputStreamEventHandler handler = StreamAdded;
            if (handler != null) {
                handler(this, e);
            }
        }
        protected virtual void OnStreamRemoved(OutputStreamEventArgs e) {
            OutputStreamEventHandler handler = StreamRemoved;
            if (handler != null) {
                handler(this, e);
            }
        }
        protected virtual void OnStreamCleared(OutputStreamEventArgs e) {
            OutputStreamEventHandler handler = StreamCleared;
            if (handler != null) {
                handler(this, e);
            }
        }
        protected virtual void OnAllStreamsCleared(EventArgs e) {
            EventHandler handler = AllStreamsCleared;
            if (handler != null) {
                handler(this, e);
            }
        }
        private void StreamWritten(object sender, EventArgs e) {
            LoadOutputStream((OutputStream)outputBuffers.EditValue);
        }
        private void InternalAddStream(OutputStream stream) {
            if (!repositoryItemComboBox.Items.Contains(stream)) {
                repositoryItemComboBox.Items.Add(stream);
                if (outputBuffers.EditValue == null) {
                    outputBuffers.EditValue = stream;
                }
            }
        }
        private void InternalRemoveStream(OutputStream stream) {
            if (repositoryItemComboBox.Items.Contains(stream)) {
                repositoryItemComboBox.Items.Remove(stream);
            }
        }
        public void AddStream(OutputStream stream) {
            streams.Add(stream);
            InternalAddStream(stream);
            OnStreamAdded(new OutputStreamEventArgs(stream));
        }
        public void RemoveStream(OutputStream stream) {
            streams.Remove(stream);
            InternalRemoveStream(stream);
            OnStreamRemoved(new OutputStreamEventArgs(stream));
        }
        public void ClearStream(OutputStream stream) {
            stream.ClearMessages();
            if (stream == (OutputStream)outputBuffers.EditValue) {
                outputBox.Text = "";
            }
            OnStreamCleared(new OutputStreamEventArgs(stream));
        }
        public void ClearAll() {
            foreach (OutputStream stream in streams) {
                ClearStream(stream);
            }
            OnAllStreamsCleared(EventArgs.Empty);
        }
        private void LoadOutputStream(OutputStream stream) {
            outputBox.Text = stream.Text;
            OnSelectedStreamChanged(new OutputStreamEventArgs(stream));
        }
        private void OutputBuffersEditValueChanged(object sender, EventArgs e) {
            OutputStream stream = (OutputStream)outputBuffers.EditValue;
            stream.Write += StreamWritten;
            LoadOutputStream(stream);
        }
        private void ClearButtonItemClick(object sender, ItemClickEventArgs e) {
            ClearStream((OutputStream)outputBuffers.EditValue);
        }
        private void ToggleWordWrapButtonItemClick(object sender, ItemClickEventArgs e) {
            outputBox.WordWrap = toggleWordWrapButton.Down;
        }
        public Output() {
            InitializeComponent();
            try { Global.Instance.RegisterService(this, GetType().GetInterface("IOutput")); }
            catch { }
        }
    }
}
